using System;
using Lypshare.Flow;
using Lypshare.Net;
using Lypshare.Net.Server;
using Lypshare.Net.Client;
using System.Threading;
using Lypshare.Flow.Types;
using System.Collections.Generic;
using System.Collections.Concurrent;

namespace Lypshare.ChatApp
{
	/// <summary>
	/// Main class.
	/// </summary>
	public class MainClass
	{
		// --------------------------------------------------------
        // Static Variables
        // --------------------------------------------------------
		
		
		/// <summary>
		/// The _ clients.
		/// </summary>
		private static ConcurrentDictionary<IConnection, ChatClient> _Clients 
			= new ConcurrentDictionary<IConnection, ChatClient>();
		
		
		/// <summary>
		/// The name of the _.
		/// </summary>
		private static String _Name = null;
		
		
		/// <summary>
		/// The _ room.
		/// </summary>
		private static String _Room = null;
		
		
		// --------------------------------------------------------
        // Static Properties
        // --------------------------------------------------------
		
		
		/// <summary>
		/// Gets the name.
		/// </summary>
		/// <value>
		/// The name.
		/// </value>
		public static String Name
		{
			get { return _Name; }
			
		} // Property: Name
		
		
		/// <summary>
		/// Gets the room.
		/// </summary>
		/// <value>
		/// The room.
		/// </value>
		public static String Room
		{
			get { return _Room; }
			
		} // Property: Room
		
		
		// --------------------------------------------------------
        // Static Functions
        // --------------------------------------------------------
		
		
		/// <summary>
        /// The entry point of the program, where the program control starts and ends.
        /// </summary>
        /// <param name='args'>
        /// The command-line arguments.
        /// </param>
        public static void Main(string[] args)
        {
            /*var accessPoint = new AccessPoint(
                "127.0.0.1", 9010, "LypsterAccessPoint");

            accessPoint.Open();
			
			var session1 = new NetworkSession(
                "127.0.0.1", 9010, "LypsterAccessPoint");
			var session2 = new NetworkSession(
                "127.0.0.1", 9010, "LypsterAccessPoint");
			
			session1.Join("Test1");
			session2.Join("Test1");
			
			Thread.Sleep(2000);
			
			while(true)
				Thread.Sleep(100);*/
			
            Console.WriteLine("--------------------------------------");
            Console.WriteLine("Lypster P2P Chat");
            Console.WriteLine("--------------------------------------");
            Console.WriteLine();
            
            Console.Write("Connect to access point...");
                        
            // Open new network session
            var session = new NetworkSession(
                "lypster.net", 9010, "LypsterAccessPoint");
                        
            // Link events
            session.ClientJoined += OnSessionClientJoined;

            Console.Write("Done\n\n");
            
            
            Console.WriteLine("Enter your name:");
			Console.ForegroundColor = ConsoleColor.Red;
            _Name = Console.ReadLine();
			Console.ForegroundColor = ConsoleColor.Gray;
            Console.WriteLine();
            
            Console.WriteLine("Enter chat room:");
			Console.ForegroundColor = ConsoleColor.Red;
            _Room = Console.ReadLine();
			Console.ForegroundColor = ConsoleColor.Gray;
            Console.WriteLine();
                            
            Console.WriteLine("Join chat room: " + _Room);
                        
            // Join specific chat room
            session.Join(_Room);

            Console.WriteLine("[Type 'Exit' for shutdown]");
            Console.WriteLine();
            Console.WriteLine();
            
			Console.ForegroundColor = ConsoleColor.White;
			
            while(true)
            {
				
                // Read input
                var input = Console.ReadLine();
				
            	Console.WriteLine();    
			
                if(input == "Exit")
                        break;
                
                foreach(var client in _Clients.Values)
                        if(client.Ready) client.Send(input);
                    
            } // while(true)
            
            foreach(var client in _Clients.Values)
                    client.Dispose();
            
			session.Shutdown();
			
            Console.WriteLine();
			Console.ForegroundColor = ConsoleColor.Gray;
            Console.WriteLine("Press enter for shutdown...");
            Console.ReadLine();
                        
        } // Main
                
                
        // --------------------------------------------------------
        // Static Handles
        // --------------------------------------------------------
                
                
        /// <summary>
        /// Raises the session client joined event.
        /// </summary>
        /// <param name='arg1'>
        /// Arg1.
        /// </param>
        /// <param name='arg2'>
        /// Arg2.
        /// </param>
        private static void OnSessionClientJoined(INetworkSession arg1, ConnectionEventArgs arg2)
        {
            var client = new ChatClient(
                    arg2.Connection);
			
			arg2.Connection.Closed += (obj) => 
				_Clients.TryRemove(
					arg2.Connection, out client);
            
            _Clients.TryAdd(
				arg2.Connection, client);
                
        } // OnSessionClientJoined
        
	} // class MainClass
} // namespace Lypshare.ChatApp